package com.longsichao.lscframe.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PointF;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;
import com.squareup.picasso.RequestCreator;
import com.squareup.picasso.Transformation;

import jp.wasabeef.picasso.transformations.BlurTransformation;
import jp.wasabeef.picasso.transformations.ColorFilterTransformation;
import jp.wasabeef.picasso.transformations.CropCircleTransformation;
import jp.wasabeef.picasso.transformations.CropSquareTransformation;
import jp.wasabeef.picasso.transformations.CropTransformation;
import jp.wasabeef.picasso.transformations.GrayscaleTransformation;
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
import jp.wasabeef.picasso.transformations.gpu.BrightnessFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.ContrastFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.InvertFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.KuwaharaFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.PixelationFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.SepiaFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.SketchFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.SwirlFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.ToonFilterTransformation;
import jp.wasabeef.picasso.transformations.gpu.VignetteFilterTransformation;

/**
 * @author SONG GUANYULONGSICHAO (leo.song[at]outlook[dot]com)
 */
@SuppressLint("AppCompatCustomView")
public class LSCImageView extends ImageView {
    private static final int DEFAULT_SIZE = -1;
    private static final int EMPTY_RES = 0;
    private int targetWidth = DEFAULT_SIZE;
    private int targetHeight = DEFAULT_SIZE;
    private int placeHolder = EMPTY_RES;
    private int error = EMPTY_RES;
    private Type type = Type.Normal;

    public LSCImageView(Context context) {
        this(context, null);
    }

    public LSCImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LSCImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public LSCImageView setType(Type type) {
        this.type = type;
        return this;
    }

    public LSCImageView setPlaceHolder(@DrawableRes int placeHolder) {
        this.placeHolder = placeHolder;
        return this;
    }

    public LSCImageView setError(@DrawableRes int error) {
        this.error = error;
        return this;
    }

    /**
     * Resize the image to the specified size in pixels.
     */
    public LSCImageView setTargetSize(int width, int height) {
        targetWidth = width;
        targetHeight = height;
        return this;
    }

    @Override
    public void setImageResource(int resId) {
        RequestCreator creator = Picasso.with(getContext()).load(resId);
        if (targetWidth != DEFAULT_SIZE && targetHeight != DEFAULT_SIZE) {
            creator.resize(targetWidth, targetHeight);
            switch (getScaleType()) {
                case CENTER_CROP:
                    creator.centerCrop();
                    break;
                case CENTER_INSIDE:
                    creator.centerInside();
                    break;
            }
        }
        if (type != Type.Normal) {
            Transformation transformation = getTransformation(type);
            if (transformation != null) {
                creator.transform(transformation);
            }
        }
        creator.into(this);
    }

    @Override
    public void setImageURI(Uri uri) {
        RequestCreator creator = Picasso.with(getContext()).load(uri);
        if (targetWidth != DEFAULT_SIZE && targetHeight != DEFAULT_SIZE) {
            creator.resize(targetWidth, targetHeight);
            switch (getScaleType()) {
                case CENTER_CROP:
                    creator.centerCrop();
                    break;
                case CENTER_INSIDE:
                    creator.centerInside();
                    break;
            }
        }
        if (type != Type.Normal) {
            Transformation transformation = getTransformation(type);
            if (transformation != null) {
                creator.transform(transformation);
            }
        }
        if (placeHolder != EMPTY_RES) {
            creator.placeholder(placeHolder);
        }
        if (error != EMPTY_RES) {
            creator.error(error);
        }
        creator.into(this);
    }

    private Transformation getTransformation(Type type) {
        Transformation transformation;
        switch (type) {
            case CropTop:
                transformation = new CropTransformation(300, 100);
                break;
            case CropCenter:
                transformation = new CropTransformation(300, 100);
                break;
            case CropBottom:
                transformation = new CropTransformation(300, 100);
                break;
            case CropSquare:
                transformation = new CropSquareTransformation();
                break;
            case CropCircle:
                transformation = new CropCircleTransformation();
                break;
            case ColorFilter:
                transformation = new ColorFilterTransformation(Color.argb(80, 255, 0, 0));
                break;
            case Grayscale:
                transformation = new GrayscaleTransformation();
                break;
            case RoundedCorners:
                transformation = new RoundedCornersTransformation(100, 0);
                break;
            case Blur:
                transformation = new BlurTransformation(getContext(), 10);
                break;
            case Toon:
                transformation = new ToonFilterTransformation(getContext());
                break;
            case Sepia:
                transformation = new SepiaFilterTransformation(getContext());
                break;
            case Contrast:
                transformation = new ContrastFilterTransformation(getContext(), 2.0f);
                break;
            case Invert:
                transformation = new InvertFilterTransformation(getContext());
                break;
            case Pixel:
                transformation = new PixelationFilterTransformation(getContext(), 20);
                break;
            case Sketch:
                transformation = new SketchFilterTransformation(getContext());
                break;
            case Swirl:
                transformation = new SwirlFilterTransformation(getContext(), 0.5f, 1.0f, new PointF(0.5f, 0.5f));
                break;
            case Brightness:
                transformation = new BrightnessFilterTransformation(getContext(), 0.5f);
                break;
            case Kuawahara:
                transformation = new KuwaharaFilterTransformation(getContext(), 25);
                break;
            case Vignette:
                transformation = new VignetteFilterTransformation(getContext(), new PointF(0.5f, 0.5f), new float[]{0.0f, 0.0f, 0.0f}, 0f, 0.75f);
                break;
            default:
                transformation = null;
        }
        return transformation;
    }

    public enum Type {
        Normal,
        CropTop,
        CropCenter,
        CropBottom,
        CropSquare,
        CropCircle,
        ColorFilter,
        Grayscale,
        RoundedCorners,
        Blur,
        Toon,
        Sepia,
        Contrast,
        Invert,
        Pixel,
        Sketch,
        Swirl,
        Brightness,
        Kuawahara,
        Vignette
    }
}
